<?php
/**
 * Класс предоставляет методы которые работают с директориями в файловой
 * структуре, и которых нету в php
 *
 *
 * @author   nrnwest@gmail.com
 */
class Arm_File_Dir
{
    /**
     * Удаляет директорию, вместе с ее содержимым, другими
     * директориями, файлами.
     *
     * @param string $path путь к директории которую нужно удалить.
     * @return bool
     */
    public function delete($path)
    {
        $path = $this->_filterPathDir($path);
        if(!is_dir($path)) {
            throw new Arm_File_Exception(Arm_Translate::_('Не существует директории: "%s"', $path));
        }
        
        $dirs = $this->getDirs($path);
        $dirsf = $dirs;
        $dirsf[] = $path;
        $files = $this->getFiles($dirsf);

        foreach ($files as $v) {
            unlink($v);
        }
          clearstatcache();
          rsort($dirs);
          $dirsError = array();
        foreach ($dirs as $v) {
            $v = $this->_filterPathDir($v);
            @$res = rmdir($v);
            if($res === false) {
                $dirsError[] = $v;
            }
        }
        clearstatcache();  
        foreach ($dirsError as $v) {
            @$res = rmdir($v); 
        }
         @$res = rmdir($path);
         return $res;
         
    }
    
    /**
     * Фильтрирует путь таким образом что всегда путь будет 
     * иметь закрывающейся последний сепаратор. 
     * @param string $path
     * @return string
     */
    protected function _filterPathDir($path)
    {
       return rtrim($path, '/\\') . DIRECTORY_SEPARATOR; 
    }
    
     /**
     * Получения всех суб директорий, с пути $path
     *
     * @param string $path начальный путь.
     */
    public function getDirs($path=null, $result = array())
    {
        $path  = rtrim($path, '/\\') . DIRECTORY_SEPARATOR;
        $array = glob($path . '*', GLOB_ONLYDIR);
        if ($array !== false) {
            $result = array_merge($result, $array);
            foreach ($array as $v) {
                $result =  $this->getDirs($v, $result);
            }
        }
        return $result;
    }


    /**
     * Получения всех файлов c пути, или с массива путей.
     * Возвращает только пути к файлам.
     *
     * @param array|string $dirs директории
     */
    public function getFiles($dirs)
    {
        $dirs = (array) $dirs;

        $result = array();
        foreach ($dirs as $v) {
           $v = rtrim($v, '/\\');
           $res =  glob($v . DIRECTORY_SEPARATOR . '*');
           foreach ($res as $file) {
              if(is_file($file)) {
                  $result[] = $file;
              }
           }
        }
        return $result;
    }
    
    /**
     * Рекусривная функция, возвращает все файлы с заданного
     * путя $path.
     *
     * @param string $path
     */
    public function getFilesRecursion($path)
    {
       $dirs = $this->getDirs($path);
       $dirs[] = $path;
       return $this->getFiles($dirs);
    }
}
